# coding:utf-8
# writingtime: 2022-6-30
# author: wanjun
# reference: Some q-rung orthopair fuzzy Hamacher aggregation operators and their application to multiple attribute group decision making with modified EDAS method
# doi: 10.1016/j.engappai.2019.103259
# examiner:
import os
from Utilities.AutoGetOperator.selectPackage import get_func


Operator_IVQ_ROFS=get_func(r'Operators/OperationOperators/OperatorIVQROF.py','Operator_IVQ_ROFS')

class Hamacher(Operator_IVQ_ROFS):

    def add(self, a1, a2, q=0, *waste1, **waste2):
        '''
        functon :Hamacher的加法规则
        :param a1: 一个模糊集, 形式:（[x,y]，[x,y]）
        :param a2: 一个模糊集, 形式:（[x,y]，[x,y]）
        :param q:
        :return: a1与a2相加的结果
        '''
        if q <= 0:
            q = self.q
        u1=pow((pow(a1[0][0],q)+pow(a2[0][0],q)-pow(a1[0][0],q)*pow(a2[0][0],q)-(1-self.x)*pow(a1[0][0],q)*pow(a2[0][0],q)
            )/(1-(1-self.x)*pow(a1[0][0],q)*pow(a2[0][0],q)),1/q)
        u2=pow((pow(a1[0][1],q)+pow(a2[0][1],q)-pow(a1[0][1],q)*pow(a2[0][1],q)-(1-self.x)*pow(a1[0][1],q)*pow(a2[0][1],q)
            )/(1-(1-self.x)*pow(a1[0][1],q)*pow(a2[0][1],q)),1/q)
        v1=(a1[1][0]*a2[1][0]
            )/(pow(self.x+(1-self.x)*(pow(a1[1][0],q)+pow(a2[1][0],q)-pow(a1[1][0],q)*pow(a2[1][0],q)),1/q))
        v2=(a1[1][1]*a2[1][1]
            )/(pow(self.x+(1-self.x)*(pow(a1[1][1],q)+pow(a2[1][1],q)-pow(a1[1][1],q)*pow(a2[1][1],q)),1/q))
        return ([u1,u2],[v1,v2])

    def multi(self, a1, a2, q=0, *waste1, **waste2):
        '''
        function: Hamacher的乘法运算
        :param a1: 一个模糊集, 形式:（[x,y]，[x,y]）
        :param a2: 一个模糊集, 形式:（[x,y]，[x,y]）:
        :return:
        '''
        if q <= 0:
            q = self.q
        u1=(a1[0][0]*a2[0][0]
            )/(pow(self.x+(1-self.x)*(pow(a1[0][0],q)+pow(a2[0][0],q)-pow(a1[0][0],q)*pow(a2[0][0],q)),1/q))
        u2=(a1[0][1]*a2[0][1]
            )/(pow(self.x+(1-self.x)*(pow(a1[0][1],q)+pow(a2[0][1],q)-pow(a1[0][1],q)*pow(a2[0][1],q)),1/q))
        v1=pow((pow(a1[1][0],q)+pow(a2[1][0],q)-pow(a1[1][0],q)*pow(a2[1][0],q)-(1-self.x)*pow(a1[1][0],q)*pow(a2[1][0],q)
            )/(1-(1-self.x)*pow(a1[1][0],q)*pow(a2[1][0],q)),1/q)
        v2=pow((pow(a1[1][1],q)+pow(a2[1][1],q)-pow(a1[1][1],q)*pow(a2[1][1],q)-(1-self.x)*pow(a1[1][1],q)*pow(a2[1][1],q)
            )/(1-(1-self.x)*pow(a1[1][1],q)*pow(a2[1][1],q)),1/q)
        return ([u1, u2], [v1, v2])

    def kmulti(self, a, k, q=0, *waste1, **waste2):
        '''
        function:Hamacher的数乘运算
        :param a: 一个模糊集, 形式:（[x,y]，[x,y]）
        :param k: ka 的常数 k
        :param q:
        :return:
        '''
        if q <= 0:
            q = self.q
        u1=(((1+(self.x-1)*(a[0][0]**q))**(self.x)-(1-(a[0][0]**q))**(self.x)
            )/((1+(self.x-1)*(a[0][0]**q))**(self.x)+(self.x-1)*((1-a[0][0]**q)**(self.x))))**(1/q)
        u2=(((1+(self.x-1)*(a[0][1]**q))**(self.x)-(1-(a[0][1]**q))**(self.x)
            )/((1+(self.x-1)*(a[0][1]**q))**(self.x)+(self.x-1)*((1-a[0][1]**q)**(self.x))))**(1/q)
        v1=((self.x**(1/q))*(a[1][0]**k)
            )/(((1+(self.x-1)*(1-a[1][0]**q))**k+(self.x-1)*(a[1][0]**(q*k)))**(1/q))
        v2=((self.x**(1/q))*(a[1][1]**k)
            )/(((1+(self.x-1)*(1-a[1][1]**q))**k+(self.x-1)*(a[1][1]**(q*k)))**(1/q))

        return ([u1,u2],[v1,v2])

    def pow(self, a, k, q=0, *waste1, **waste2):
        '''
        function： Hamacher的幂运算
        :param a:  一个模糊集, 形式:（[x,y]，[x,y]）
        :param k:  ka 的常数 k
        :param q:
        :return:
        '''
        if q <= 0:
            q = self.q
        u1=((self.x**(1/q))*(a[0][0]**k)
            )/(((1+(self.x-1)*(1-a[0][0]**q))**k+(self.x-1)*(a[0][0]**(q*k)))**(1/q))
        u2=((self.x**(1/q))*(a[0][1]**k)
            )/(((1+(self.x-1)*(1-a[0][1]**q))**k+(self.x-1)*(a[0][1]**(q*k)))**(1/q))
        v1=(((1+(self.x-1)*(a[1][0]**q))**(self.x)-(1-(a[1][0]**q))**(self.x)
            )/((1+(self.x-1)*(a[1][0]**q))**(self.x)+(self.x-1)*((1-a[1][0]**q)**(self.x))))**(1/q)
        v2=(((1+(self.x-1)*(a[1][1]**q))**(self.x)-(1-(a[1][1]**q))**(self.x)
            )/((1+(self.x-1)*(a[1][1]**q))**(self.x)+(self.x-1)*((1-a[1][1]**q)**(self.x))))**(1/q)

        return ([u1,u2],[v1,v2])


class HamacherA(Hamacher):

    def getResult(self):
        '''
        function：基础的算数平均公式
        :return: AA公式计算的结果
        '''
        result=self.data_list[0]
        for i in range(1,len(self.data_list)):
            result=self.add(result,self.data_list[i])
        result=self.kmulti(result,1/len(self.data_list))

        return result

class HamacherGA(Hamacher):

    def getResult(self):
        '''
        function：基础的算数平均公式
        :return: AA公式计算的结果
        '''
        result = self.data_list[0]
        for i in range(1, len(self.data_list)):
            result = self.multi(result, self.data_list[i])
        result = self.pow(result, 1 / len(self.data_list))

        return result

class HamacherWA(Hamacher):

    def getResult(self):
        '''
        function：基础的加权算数平均公式
        :return: WAA公式计算的结果
        '''
        result = self.kmulti(self.data_list[0],self.weight_list[0])
        for i in range(1, len(self.data_list)):
            temp=self.kmulti(self.data_list[i],self.weight_list[i])
            result = self.add(result, temp)

        return result

class HamacherWGA(Hamacher):

    def getResult(self):
        '''
        function：基础的加权几何平均公式
        :return: WAA公式计算的结果
        '''
        result = self.pow(self.data_list[0],self.weight_list[0])
        for i in range(1, len(self.data_list)):
            temp=self.pow(self.data_list[i],self.weight_list[i])
            result = self.multi(result, temp)

        return result

class HamacherOWA(Hamacher):

    def getResult(self):
        '''
        function：基础的有序加权算数平均公式
        :return: OWAA公式计算的结果
        '''
        # 将 数据集备份，将类中数据集属性 替换为 排序后的数据集
        data_list = self.data_list
        self.data_list = self.sortdata()

        result = self.kmulti(self.data_list[0],self.weight_list[0])
        for i in range(1, len(self.data_list)):
            temp=self.kmulti(self.data_list[i],self.weight_list[i])
            result = self.add(result, temp)

        # 还原数据集
        self.data_list = data_list
        return result

if __name__=="__main__":
    list1 = [([0.85, 0.95], [0.1, 0.2]), ([0.8, 0.9], [0.1, 0.2]), ([0.85, 0.95], [0.1, 0.2]), ([0.7, 0.8], [0.2, 0.3]),
        ([0.4, 0.5], [0.5, 0.6])]
    a = HamacherA(list1, [0.2, 0.2, 0.2, 0.2, 0.2], 3)
    print(a.getResult())

    # a=Hamacher().multi(data_list[0],([1,1],[0,0]));print(a)
    # print(Hamacher().multi(data_list[0], data_list[0]))
    # print(Hamacher().pow(data_list[0], 2))
    # a = Hamacher().add(data_list[0], ([0, 0],[1, 1]))

